home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1997 February / macformat-047.iso / Shareware Plus / Developers / PlayerPRO 4.5.3 Dev.Kit / Plug-Ins / Instruments Import⁄Export Plugs / System7.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-13  |  10.3 KB  |  451 lines  |  [TEXT/CWIE]

  1. /*    SND                */
  2. /*  IMPORT/EXPORT    */
  3. /*    v 1.0            */
  4. /*    1996 by ANR        */
  5.  
  6. //    Usage:
  7.  
  8. #include "PPPlug.h"
  9. #include "sound.h"
  10. #include "soundinput.h"
  11.  
  12. Ptr MyExp1to3( Ptr sound, unsigned long numSampleFrames);
  13. Ptr MyExp1to6( Ptr sound, unsigned long numSampleFrames);
  14.  
  15. #if defined(powerc) || defined(__powerc)
  16. enum {
  17.         PlayerPROPlug = kCStackBased
  18.         | RESULT_SIZE(SIZE_CODE( sizeof(OSErr)))
  19.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof( OSType)))
  20.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof( InstrData*)))
  21.         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof( sData**)))
  22.         | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof( short*)))
  23.         | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof( FSSpec*)))
  24.         | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof( PPInfoPlug*)))
  25. };
  26.  
  27. ProcInfoType __procinfo = PlayerPROPlug;
  28. #else
  29. #include <A4Stuff.h>
  30. #endif
  31.  
  32.  
  33. void AddLoopToSndHandle( Handle sound, long Start, long End)
  34. {
  35.     Ptr             soundPtr;
  36.     short             soundFormat;
  37.     short             numSynths, numCmds;
  38.     long             offset;
  39.     SoundHeaderPtr     header;
  40.     CmpSoundHeader    *CmpHeader;
  41.     ExtSoundHeader    *ExtHeader;
  42.     OSErr             result;
  43.         
  44.     // make the sound safe to use at interrupt time.
  45.     HLock( sound);
  46.     soundPtr = *sound;
  47.     
  48.     // determine what format sound we have. 
  49.     soundFormat = *(short*)soundPtr;
  50.     
  51.     switch(soundFormat)
  52.     {
  53.         case 1:                        // format 1 sound. 
  54.             // look inside the format 1 resource and deduce offsets. 
  55.             numSynths = ((short*)soundPtr)[1];                    // get # synths. 
  56.             numCmds = *(short*)(soundPtr+4+numSynths*6);        // get # commands. 
  57.         break;
  58.         
  59.         case 2:                        // format 2 sound. 
  60.             numSynths = 0;            // format 2 sounds have no synth's. 
  61.             numCmds = ((short*)soundPtr)[2];
  62.         break;
  63.         
  64.         default:                    // jack says, what about 12? or 6? 
  65.             DebugStr("\p NSndToHandle... Burkk");
  66.     } 
  67.  
  68.     // compute address of sound header.
  69.     offset = 6 + 6*numSynths + 8*numCmds;
  70.     header = (SoundHeaderPtr) (StripAddress(*sound) + offset);
  71.         
  72.     switch( header->encode)
  73.     {
  74.         case cmpSH:
  75.             CmpHeader = (CmpSoundHeader*) header;
  76.             if( CmpHeader->sampleSize == 16) { Start /= 2; End /= 2; }
  77.             
  78.             CmpHeader->loopStart    = Start;
  79.             CmpHeader->loopEnd        = End;
  80.         break;
  81.  
  82.         case extSH:
  83.             ExtHeader = (ExtSoundHeader*) header;
  84.             if( ExtHeader->sampleSize == 16) { Start /= 2; End /= 2; }
  85.             
  86.             ExtHeader->loopStart    = Start;
  87.             ExtHeader->loopEnd        = End;
  88.         break;
  89.         
  90.         case stdSH:
  91.             header->loopStart    = Start;
  92.             header->loopEnd        = End;
  93.         break;
  94.     }
  95.     
  96.     HUnlock( sound);
  97. }
  98.  
  99. Ptr SndToPtr( Ptr soundPtr, long *loopStart, long *loopEnd, short *sampleSize, unsigned long *sampleRate, long *baseFreq)
  100. {
  101.     short             soundFormat, numChannels;
  102.     short             numSynths, numCmds, CompressID;
  103.     long             offset, MusSize;
  104.     SoundHeaderPtr     header;
  105.     CmpSoundHeader    *CmpHeader;
  106.     ExtSoundHeader    *ExtHeader;
  107.     SndCommand         cmd;
  108.     OSErr             result;
  109.     long            i,x, numFrames;
  110.     Boolean            change = false;
  111.     Str255            aStr;
  112.     
  113.     *loopStart = 0;
  114.     *loopEnd = 0;
  115.     *sampleSize = 8;
  116.     
  117.     // determine what format sound we have.
  118.     soundFormat = *(short*) soundPtr;
  119.     
  120.     switch( soundFormat)
  121.     {
  122.         case 1:                        // format 1 sound.
  123.             // look inside the format 1 resource and deduce offsets.
  124.             numSynths = ((short*)soundPtr)[1];                    // get # synths. 
  125.             numCmds = *(short*)(soundPtr+4+numSynths*6);        // get # commands.
  126.         break;
  127.         
  128.         case 2:                        // format 2 sound. 
  129.             numSynths = 0;            // format 2 sounds have no synth's. 
  130.             numCmds = ((short*)soundPtr)[2];
  131.         break;
  132.         
  133.         default:                    // jack says, what about 12? or 6?
  134.             DebugStr("\p NSndToHandle... Burkk");
  135.         break;
  136.     } 
  137.  
  138.     // compute address of sound header.
  139.     offset = 6 + 6*numSynths + 8*numCmds;
  140.     header = (SoundHeaderPtr) ( ((Ptr) soundPtr) + offset);
  141.     
  142.     switch( header->encode)
  143.     {
  144.         case cmpSH:
  145.             CmpHeader = (CmpSoundHeader*) header;
  146.             CompressID = CmpHeader->compressionID;
  147.             numChannels = CmpHeader->numChannels;            
  148.  
  149.             *loopStart = CmpHeader->loopStart;
  150.             *loopEnd = CmpHeader->loopEnd;
  151.             *sampleSize = CmpHeader->sampleSize;
  152.             
  153.             if( sampleRate != 0L)     *sampleRate    = CmpHeader->sampleRate;
  154.             if( baseFreq != 0L)     *baseFreq     = CmpHeader->baseFrequency;
  155.  
  156.             MusSize = (*CmpHeader).numFrames;
  157.             
  158.             BlockMove( (*CmpHeader).sampleArea, soundPtr, MusSize);
  159.                     
  160.             switch( CompressID )
  161.             {
  162.                 case threeToOne:
  163.                     MusSize *= 2;
  164.                     soundPtr = MyExp1to3( soundPtr, MusSize);
  165.                     MusSize *= 3;
  166.                 break;
  167.                 
  168.                 case sixToOne:
  169.                     soundPtr = MyExp1to6( soundPtr, MusSize);
  170.                     MusSize *= 6;
  171.                 break;
  172.                 
  173.                 default:
  174.                     return 0L;
  175.                 break;
  176.             }
  177.             
  178.         break;
  179.  
  180.         case extSH:
  181.             ExtHeader = (ExtSoundHeader*) header;
  182.             
  183.             MusSize = ExtHeader->numFrames;
  184.             numChannels = ExtHeader->numChannels;
  185.  
  186.             *loopStart = ExtHeader->loopStart;
  187.             *loopEnd = ExtHeader->loopEnd;
  188.             *sampleSize = ExtHeader->sampleSize;
  189.             
  190.             if( sampleRate != 0L)     *sampleRate    = ExtHeader->sampleRate;
  191.             if( baseFreq != 0L)     *baseFreq     = ExtHeader->baseFrequency;
  192.             
  193.             if( *sampleSize == 16)
  194.             {
  195.                 MusSize *= 2;
  196.                 *loopStart *= 2;
  197.                 *loopEnd *= 2;
  198.             }
  199.             
  200.             if( numChannels == 1) BlockMove( ExtHeader->sampleArea, soundPtr, MusSize);
  201.             else
  202.             {
  203.                 if( *sampleSize == 8)
  204.                 {
  205.                     for( i = 0; i < MusSize; i ++)
  206.                     {
  207.                         soundPtr[ i] = ExtHeader->sampleArea[ i * numChannels];
  208.                     }
  209.                 }
  210.                 else
  211.                 {
  212.                     MusSize /= 2;
  213.                     for( i = 0; i < MusSize; i ++)
  214.                     {
  215.                         ((short*) soundPtr)[ i] = ((short*) ExtHeader->sampleArea)[ i * numChannels];
  216.                     }
  217.                     MusSize *= 2;
  218.                 }
  219.             }
  220.         break;
  221.         
  222.         default:
  223.         case stdSH:
  224.             *loopStart = header->loopStart;
  225.             *loopEnd = header->loopEnd;
  226.             
  227.             if( sampleRate != 0L)     *sampleRate    = header->sampleRate;
  228.             if( baseFreq != 0L)     *baseFreq     = header->baseFrequency;
  229.             
  230.             MusSize = header->length;
  231.             BlockMove( (*header).sampleArea, soundPtr, MusSize);
  232.         break;
  233.     }
  234.     SetPtrSize( soundPtr, MusSize);
  235.     if( MemError() != noErr) Debugger();
  236.     
  237.     if( *sampleSize == 8) ConvertInstrumentIn( (Byte*) soundPtr, MusSize);
  238.     
  239.     if( *loopEnd - *loopStart < 4) { *loopEnd = 0;    *loopStart = 0;}
  240.     
  241.     return soundPtr;
  242. }
  243.  
  244.  
  245. OSErr TestSND( short *soundPtr)
  246. {
  247.     if( *soundPtr == 1 || *soundPtr == 2) return noErr;
  248.     else return MADFileNotSupportedByThisPlug;
  249. }
  250.  
  251. Ptr IMPL( long *lS, long *lE, long *bFreq, short *sS, unsigned long *rate, FSSpec *AlienFileFSSpec)
  252. {
  253.     Handle            tempHandle;
  254.     Ptr             theSound = 0L;
  255.     short            iFileRefI;
  256.     OSErr            myErr = noErr;    
  257.         
  258.     iFileRefI = FSpOpenResFile( AlienFileFSSpec, fsCurPerm);
  259.     
  260.     if( ResError())
  261.     {
  262.         CloseResFile( iFileRefI);    myErr = ResError();        goto End;
  263.     }
  264.     
  265.     UseResFile( iFileRefI);
  266.     
  267.     if( Count1Resources( 'snd ') == 0)
  268.     {
  269.         CloseResFile( iFileRefI);    myErr = ResError();        goto End;
  270.     }
  271.     
  272.     tempHandle = Get1IndResource('snd ', 1);
  273.     if( tempHandle != 0L)
  274.     {
  275.         DetachResource( tempHandle);
  276.         
  277.         theSound = NewPtr( GetHandleSize( tempHandle));
  278.         if( theSound != 0L)
  279.         {
  280.             HLock( tempHandle);
  281.             BlockMove( *tempHandle, theSound, GetHandleSize( tempHandle));
  282.             HUnlock( tempHandle);
  283.             
  284.             theSound = SndToPtr( theSound, lS, lE, sS, rate, bFreq);
  285.             
  286.             if( theSound == 0L)
  287.             {
  288.                 DisposeHandle( tempHandle);
  289.                 CloseResFile( iFileRefI);
  290.                 myErr = MADNeedMemory;
  291.                 goto End;
  292.             }
  293.         }
  294.         else
  295.         {
  296.             DisposeHandle( tempHandle);
  297.             CloseResFile( iFileRefI);
  298.             myErr = MADNeedMemory;
  299.             goto End;
  300.         }
  301.         
  302.         DisposeHandle( tempHandle);
  303.         tempHandle = 0L;
  304.     }
  305.     else
  306.     {
  307.         CloseResFile( iFileRefI);
  308.         myErr = MADNeedMemory;
  309.         goto End;
  310.     }
  311.     CloseResFile( iFileRefI);
  312.     
  313.     End:;
  314.     
  315.     if( myErr != noErr) return 0L;
  316.     else return theSound;
  317. }
  318.  
  319. OSErr main(        OSType                    order,                        // Order to execute
  320.                 InstrData                *InsHeader,                    // Ptr on instrument header
  321.                 sData                    **sample,                    // Ptr on samples data
  322.                 short                    *sampleID,                    // If you need to replace/add only a sample, not replace the entire instrument (by example for 'AIFF' sound)
  323.                                                                     // If sampleID == -1 : add sample else replace selected sample.
  324.                 FSSpec                    *AlienFileFSSpec,            // IN/OUT file
  325.                 PPInfoPlug                *thePPInfoPlug)
  326. {
  327.     OSErr    myErr = noErr;
  328.     Ptr        AlienFile;
  329.     short    iFileRefI;
  330.     long    inOutBytes;
  331.     
  332.     #ifndef powerc
  333.         long    oldA4 = SetCurrentA4();             //this call is necessary for strings in 68k code resources
  334.     #endif
  335.     
  336.     switch( order)
  337.     {
  338.         case 'PLAY':
  339.         {
  340.             long            lS, lE, bFreq;
  341.             short            sS;
  342.             unsigned long    rate;
  343.             Ptr                theSound;
  344.             
  345.             theSound = IMPL( &lS, &lE, &bFreq, &sS, &rate, AlienFileFSSpec);
  346.             
  347.             if( theSound != 0L)
  348.             {
  349.                 myErr = CallRPlaySoundUPP( theSound, GetPtrSize( theSound), 0, 0xFF, sS, lS, lE, rate);
  350.                 
  351.                 DisposePtr( theSound);
  352.                 theSound = 0L;
  353.             }
  354.         }
  355.         break;
  356.         
  357.         case 'IMPL':
  358.         {
  359.             long            lS, lE, bFreq;
  360.             short            sS;
  361.             unsigned long    rate;
  362.             Ptr                theSound;
  363.             
  364.             theSound = IMPL( &lS, &lE, &bFreq, &sS, &rate, AlienFileFSSpec);
  365.             
  366.             if( theSound != 0L)
  367.             {
  368.                 AddSoundToMAD( theSound, lS, lE, sS, bFreq, rate, AlienFileFSSpec->name, InsHeader, sample, sampleID);
  369.                 myErr = noErr;
  370.             }
  371.             else myErr = MADNeedMemory;
  372.         }
  373.         break;
  374.         
  375.         case 'TEST':
  376.             myErr = noErr;
  377.             
  378.             iFileRefI = FSpOpenResFile( AlienFileFSSpec, fsCurPerm);
  379.             
  380.             if( ResError())
  381.             {
  382.                 CloseResFile( iFileRefI);    myErr = ResError();        goto End;
  383.             }
  384.             
  385.             UseResFile( iFileRefI);
  386.             
  387.             if( Count1Resources( 'snd ') == 0) myErr = MADFileNotSupportedByThisPlug;
  388.             
  389.             CloseResFile( iFileRefI);
  390.         break;
  391.         
  392.         case 'EXPL':
  393.             if( *sampleID >= 0)
  394.             {
  395.                 sData     *curData = sample[ *sampleID];
  396.                 short    temp, fRefNum;
  397.                 Handle    tempHandle;
  398.                 
  399.                 tempHandle = NewHandle( 2048L);
  400.                 
  401.                 inOutBytes = curData->size;
  402.                 
  403.                 SetupSndHeader(        (SndListHandle) tempHandle,
  404.                                     1,
  405.                                     ((unsigned long) curData->c2spd)<<16L,
  406.                                     curData->amp,
  407.                                     'NONE',
  408.                                     60 - curData->relNote,
  409.                                     inOutBytes,
  410.                                     &temp);
  411.                 
  412.                 SetHandleSize( tempHandle, inOutBytes + temp);
  413.                 
  414.                 HLock( tempHandle);
  415.                 BlockMove( curData->data, *tempHandle + temp, inOutBytes);
  416.                 
  417.                 if( curData->amp == 8) ConvertInstrumentIn( (Byte*) *tempHandle + temp, inOutBytes);
  418.                 
  419.                 HUnlock( tempHandle);
  420.                 
  421.                 AddLoopToSndHandle(    tempHandle,
  422.                                     curData->loopBeg,
  423.                                     curData->loopBeg + curData->loopSize);
  424.                 
  425.                 FSpDelete( AlienFileFSSpec);
  426.                 FSpCreateResFile( AlienFileFSSpec, 'movr', 'sfil', smCurrentScript);
  427.                 fRefNum = FSpOpenResFile( AlienFileFSSpec, fsCurPerm);
  428.                 UseResFile( fRefNum);
  429.                 AddResource( tempHandle, 'snd ', 7438, AlienFileFSSpec->name);
  430.                 WriteResource( tempHandle);
  431.                 DetachResource( tempHandle);
  432.                 
  433.                 DisposeHandle( tempHandle);
  434.                 
  435.                 CloseResFile( fRefNum);
  436.             }
  437.         break;
  438.         
  439.         default:
  440.             myErr = MADOrderNotImplemented;
  441.         break;
  442.     }
  443.     
  444.     End:
  445.     
  446.     #ifndef powerc
  447.         SetA4( oldA4);
  448.     #endif
  449.     
  450.     return myErr;
  451. }